#include <string>
#include <map>
#include <fstream>
#include <iostream>
#include <sstream>

using namespace std;

typedef map<string, float> flexi_para_type;

int init_flexi(flexi_para_type& flexi_map, string flexi_file_name)
{
	ifstream   in(flexi_file_name.c_str());
	if(!in) 
	{ 
		cerr<<"open " << flexi_file_name.c_str() << " error!"<<endl;
		return 0;
	} 

	int flexi_size = 0; 
	string   s,line, sub_line;
	float flexi_value = 0.0f;
	

	getline(in,   line);
	flexi_size = line.find_first_of(' ');
	sub_line = line.substr(0, flexi_size);
	istringstream string2float(line.substr(flexi_size));
	string2float >> flexi_value;

	flexi_map.insert(make_pair(sub_line, flexi_value));

	while(getline(in,   line))   
	{
		flexi_size = line.find_first_of(' ');
		sub_line = line.substr(0, flexi_size);
		istringstream string2float(line.substr(flexi_size));
		string2float >> flexi_value;

		flexi_map.insert(make_pair(sub_line, flexi_value));
	} 

	in.close();

	return flexi_size;
}

float check_value(flexi_para_type& flexi_map, string DNA_chip)
{
	flexi_para_type::iterator it = flexi_map.find(DNA_chip); 
	if(it == flexi_map.end()) {
		return 0.0f;
	}
	else {
		return it->second;
	}
}

int check_req(flexi_para_type& flexi_map, string req_file_name, int flexi_size, int windows_size, string outfile_name)
{
	ifstream   in(req_file_name.c_str());
	if(!in) { cerr<<"open " << req_file_name.c_str() << " error!"<<endl; return 0; } 

	ofstream	out(outfile_name.c_str());
	if(!in) { cerr<<"open " << outfile_name.c_str() << " error!"<<endl; return 0; } 

	string   s,line, sub_line;

	int loop = 0; 
	

	int sub_str_end = windows_size - flexi_size +1;

	while(getline(in,   line))   
	{	
		loop++;
		int str_end = line.size();
		str_end = str_end - windows_size + 1;

		for( int i = 0; i <= str_end; i ++ )
		{
			float sub_line_value = 0.0f;
			sub_line = line.substr(i, windows_size);

			for(int j = 0; j <= sub_str_end; j++)
			{
				float subvalue = check_value(flexi_map, sub_line.substr(j, flexi_size));;
				sub_line_value += subvalue;
			}
			out << sub_line_value/sub_str_end << ",";
		}
		out <<"\n";

		if((loop %100) == 0) cout << loop << "\n";
	} 

	in.close();
	out.close();
	return 0; 
}

int init_para(string init_file_name, string& input_filename, string& oput_filename, string& parameter_filename, int& windows_size)
{
	ifstream   in(init_file_name.c_str());
	if(!in) { cerr<<"open " << init_file_name.c_str() << " error!"<<endl;  return 0;} 

	string line, sub_line1, sub_line2;
	while(getline(in,   line))   
	{
		sub_line1 = line.substr(0, line.find_first_of('='));
		sub_line1 = sub_line1.substr(0, sub_line1.find_last_not_of(' ')+1);
		sub_line2 = line.substr(line.find_first_of('=')+1);
		sub_line2 = sub_line2.substr(sub_line2.find_first_not_of(' '));

		if(!sub_line1.compare("input"))
		{
			input_filename = sub_line2;
		}
		if(!sub_line1.compare("output"))
		{
			oput_filename = sub_line2;
		}
		if(!sub_line1.compare("flexibility_parameter"))
		{
			parameter_filename = sub_line2;
		}
		if(!sub_line1.compare("window_width"))
		{
			istringstream string2float(sub_line2);
			string2float >> windows_size;
		}
	}

	return 1;
}
/*
input = input_filename
output = output_filename
flexibility_parameter = parameter_filename
window_width = 6
*/
int main(int argc, char** argv)
{
	flexi_para_type flexi_map;
	int flexi_size;
	int windows_size = 12;
	string input_filename = "seq";
	string oput_filename = "out";
	string parameter_filename = "tetranucleotide";


	if( !init_para("flexibility.ini", input_filename, oput_filename, parameter_filename, windows_size )) return 0;

	flexi_size = init_flexi(flexi_map, parameter_filename);

	check_req(flexi_map, input_filename, flexi_size, windows_size, oput_filename);
	return 0;
}